package com.youxin.chat.pay.service.manager;

import com.alibaba.fastjson.JSONObject;
import com.alicp.jetcache.Cache;
import com.alicp.jetcache.anno.CacheType;
import com.alicp.jetcache.anno.CreateCache;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.youxin.base.BaseResultCode;
import com.youxin.chat.pay.context.TransactionContext;
import com.youxin.chat.pay.enums.CashStatusEnum;
import com.youxin.chat.pay.enums.OrderStatusEnum;
import com.youxin.chat.pay.mapper.*;
import com.youxin.chat.pay.model.*;
import com.youxin.exception.SystemException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * description: UserCashManager <br>
 * date: 2020/3/1 12:57 <br>
 * author: llkj <br>
 * version: 1.0 <br>
 */
@Service
public class UserCashManager {

    private static final Logger logger = LoggerFactory.getLogger(UserCashManager.class);
    @Resource
    private UserWalletMapper userWalletMapper;

    @Resource
    private UserCashMapper userCashMapper;

    @Resource
    private ChannelCashMapper channelCashMapper;

    @Resource
    private CommonOrderMapper commonOrderMapper;

    @Resource
    private ChannelCardMapper channelCardMapper;

    @Resource
    private TransactionDetailMapper transactionDetailMapper;

    @Resource
    private RedisTemplate redisTemplate;

    @CreateCache(name = "user.friend.list.")
    private Cache<String, Object> jetcache;

    @Transactional
    public int doCashProcessing(UserCash userCash, CommonOrder commonOrder, ChannelCash channelCash) {
        int count = userWalletMapper.doCashAudit(userCash.getCashAmount(), userCash.getUserNo());
        if (count < 1) {
            logger.error("可提现金额不足,data={}", JSONObject.toJSONString(userCash));
            throw new SystemException(BaseResultCode.BALANCE_NOT_ENOUGH, "可提现余额不足");
        }
        userCashMapper.insert(userCash);
        commonOrderMapper.insert(commonOrder);
        channelCashMapper.insert(channelCash);
        return 1;
    }

    @Transactional
    public int doCashFail(UserCash userCash) {
        int count = channelCashMapper.doCashFinish(CashStatusEnum.FAIL.getStatus(), userCash.getCashNo());
        if (count < 1) {
            logger.error("更新渠道订单状态失败，userCash={}", JSONObject.toJSONString(userCash));
            throw new SystemException(BaseResultCode.INTERNAL_ERROR, "系统内部异常");
        }
        count = userCashMapper.doCashFinish(CashStatusEnum.FAIL.getStatus(), userCash.getCashNo());
        if (count < 1) {
            logger.error("提现状态已变,userCash={}", JSONObject.toJSONString(userCash));
            throw new SystemException(BaseResultCode.INTERNAL_ERROR, "系统内部异常");
        }
        count = userWalletMapper.doCashFail(userCash.getCashAmount(), userCash.getUserNo());
        if (count < 1) {
            logger.error("余额状态变更失败,userCash={}", JSONObject.toJSONString(userCash));
            throw new SystemException(BaseResultCode.INTERNAL_ERROR, "系统内部异常");
        }
        count = commonOrderMapper.changeOrderStatus(OrderStatusEnum.PAY_FAIL.getStatus(), userCash.getCashNo());
        if (count < 1) {
            logger.error("通用订单更新失败,userCash={}", JSONObject.toJSONString(userCash));
            throw new SystemException(BaseResultCode.INTERNAL_ERROR, "系统内部异常");
        }
        return count;
    }

    @Transactional
    public int doCashSuccess(UserCash userCash) {
        int count = channelCashMapper.doCashFinish(CashStatusEnum.SUCCESS.getStatus(), userCash.getCashNo());
        if (count < 1) {
            logger.error("更新渠道订单状态失败，userCash={}", JSONObject.toJSONString(userCash));
            throw new SystemException(BaseResultCode.INTERNAL_ERROR, "系统内部异常");
        }
        count = userCashMapper.doCashFinish(CashStatusEnum.SUCCESS.getStatus(), userCash.getCashNo());
        if (count < 1) {
            logger.error("提现状态已变,userCash={}", JSONObject.toJSONString(userCash));
            throw new SystemException(BaseResultCode.INTERNAL_ERROR, "系统内部异常");
        }
        count = userWalletMapper.doCashSuccess(userCash.getCashAmount(), userCash.getUserNo());
        if (count < 1) {
            logger.error("余额状态变更失败,userCash={}", JSONObject.toJSONString(userCash));
            throw new SystemException(BaseResultCode.INTERNAL_ERROR, "系统内部异常");
        }
        UserWallet userWallet = userWalletMapper.selectById(userCash.getUserNo());
        ChannelCash channelCash = channelCashMapper.selectOne(new LambdaQueryWrapper<ChannelCash>().eq(ChannelCash::getCashNo, userCash.getCashNo()));
        TransactionDetail transactionDetail = TransactionContext.buildTransactionDetail(userCash, channelCash, userWallet.getAgentNo());
        count = transactionDetailMapper.insert(transactionDetail);
        if (count < 1) {
            logger.error("结算信息更新失败,userCash={}", JSONObject.toJSONString(userCash));
            throw new SystemException(BaseResultCode.INTERNAL_ERROR, "系统内部异常");
        }
        count = commonOrderMapper.changeOrderStatus(OrderStatusEnum.PAY_SUCCESS.getStatus(), userCash.getCashNo());
        if (count < 1) {
            logger.error("通用订单更新失败,userCash={}", JSONObject.toJSONString(userCash));
            throw new SystemException(BaseResultCode.INTERNAL_ERROR, "系统内部异常");
        }
        return count;
    }

    public void checkUserRate(String userNo) {
        if (redisTemplate.opsForValue().getAndSet("pay.user.cash.limit" + userNo, 1) != null) {
            logger.error("用户请求频繁,checkUserRate={}", JSONObject.toJSONString(userNo));
            throw new SystemException(BaseResultCode.REQUEST_FREQUENT, "请求过于频繁");
        }
        redisTemplate.expire("pay.user.cash.limit" + userNo, 1, TimeUnit.MINUTES);
    }

    public void removeUserRate(String userNo) {
        redisTemplate.delete("pay.user.cash.limit" + userNo);
    }

}
